﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using devtm.Types;
using System.IO;
using devtm.Types.LazyLoading;
using System.ComponentModel;

namespace devtm.Helpers
{

    public static class TypeHelper
    {

        private static AssemblyDescriptionCollection Gac;
        static TypeHelper()
        {
            Gac = new AssemblyDescriptionCollection();
        }


        private static List<String> list = new List<string>();
        public static IEnumerable<String> CheckReferences(this Assembly ass)
        {

            list.Add(ass.FullName);

            foreach (System.Reflection.AssemblyName item in ass.GetReferencedAssemblies())
            {


                if (Gac.ContainsAssembly(item.FullName))
                    continue;

                try
                {
                    Assembly assemblyTest = Assembly.LoadWithPartialName(item.FullName);
                    continue;
                }
                catch (Exception)
                {
                    
                }
                


                if (!VerifyFile(ClsGetTypes.Directories, item))
                    yield return item.FullName;


                if (item.FullName.Contains(","))
                {
                    Assembly ass1 = System.Reflection.Assembly.Load(item.FullName);
                    if (!list.Contains(ass1.FullName))
                        foreach (string item2 in CheckReferences(ass1))
                            yield return item.FullName;
                }
                else
                {

                    Assembly ass1 = System.Reflection.Assembly.LoadFile(item.FullName);
                    if (!list.Contains(ass1.FullName))
                        foreach (string item2 in CheckReferences(ass1))
                            yield return item.FullName;

                }


            }


        }



        private static bool VerifyFile(IEnumerable<DirectoryInfo> dirs, System.Reflection.AssemblyName item)
        {
            if (dirs == null)
                return false;

            foreach (DirectoryInfo dir in dirs)
                if (dir.GetFiles(item.Name + ".dll", SearchOption.AllDirectories).Count() > 0)
                    return true;

            return false;

        }

        public static void LoadAssembly(this Assembly ass)
        {

            foreach (System.Reflection.AssemblyName item in ass.GetReferencedAssemblies())
            {

                Assembly ass1 = AppDomain.CurrentDomain.Load(item.FullName);

                LoadAssembly(ass1);

            }


        }



        #region Attribute


        public static T GetAttribute<T>(this Type type) where T: Attribute
        {
            return (T)Attribute.GetCustomAttribute(type, typeof(T));
        }


        public static string DisplayName(this Type type)
        {
            DisplayNameAttribute ret = GetAttribute<DisplayNameAttribute>(type);
            if (ret == null)
                return string.Empty;

            return ret.DisplayName;
        }

        public static string Description(this Type type)
        {
            DescriptionAttribute ret = GetAttribute<DescriptionAttribute>(type);
            if (ret == null)
                return string.Empty;

            return ret.Description;
        }

        #endregion
    }
}
